﻿using System;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using WindowsPhoneEssentials.Testing;
using WindowsPhoneEssentials.Threading;
using WindowsPhoneMVC.Navigation;
using WindowsPhoneMVC.Tests.ActionResults.Fakes;
using WindowsPhoneMVC.Tests.Navigation.Fakes;

namespace WindowsPhoneMVC.Tests.ActionResults
{
    [TestClass]
    public class ViewResultTests
    {
        private ViewResultImpl resultUnderTest;
        private ViewResultTestViewModel viewResultTestViewModel;
        private FakePhoenixApplication phoenixApplication;
        private FakeViewLocator viewLocator;
        private FakeNavigator navigator;

        [TestInitialize]
        public void Setup()
        {
            Execute.SetOnUIThreadPassthrough();
            phoenixApplication = new FakePhoenixApplication();
            var navigationRequest = new NavigationRequest("frame", "controller", "action");
            viewLocator = new FakeViewLocator();
            navigator = new FakeNavigator();
            viewLocator.RegisterView("controller", "TestView", new PhoneApplicationPage());
            var navigationContext = new NavigationContext(navigator, viewLocator, null, phoenixApplication, navigationRequest);
            viewResultTestViewModel = new ViewResultTestViewModel();
            resultUnderTest = new ViewResultImpl("TestView", viewResultTestViewModel, navigationContext);
        }

        [TestMethod]
        public void viewmodel_notified_when_application_obscured()
        {
            // arrange
            resultUnderTest.Execute();

            // act
            phoenixApplication.OnObscured(new ObscuredEventArgs(false));

            // assert
            Assert.IsTrue(viewResultTestViewModel.WasObscured);
        }

        [TestMethod]
        public void viewmodel_no_longer_is_notified_when_obscured_after_result_disposal()
        {
            // arrange
            resultUnderTest.Execute();
            resultUnderTest.Dispose();

            // act
            phoenixApplication.OnObscured(new ObscuredEventArgs(false));

            // assert
            Assert.IsFalse(viewResultTestViewModel.WasObscured);
        }

        [TestMethod]
        public void viewmodel_notified_when_application_unobscured()
        {
            // arrange
            resultUnderTest.Execute();

            // act
            phoenixApplication.OnUnobscured(EventArgs.Empty);

            // assert
            Assert.IsTrue(viewResultTestViewModel.WasUnobscured);
        }

        [TestMethod]
        public void viewmodel_no_longer_is_notified_when_unobscured_after_result_disposal()
        {
            // arrange
            resultUnderTest.Execute();
            resultUnderTest.Dispose();

            // act
            phoenixApplication.OnUnobscured(EventArgs.Empty);

            // assert
            Assert.IsFalse(viewResultTestViewModel.WasUnobscured);
        }

        [TestMethod]
        public void viewmodel_notified_when_application_activated()
        {
            // arrange
            resultUnderTest.Execute();

            // act
            phoenixApplication.OnActivated(new ActivatedEventArgs());

            // assert
            Assert.IsTrue(viewResultTestViewModel.WasActivated);
        }

        [TestMethod]
        public void viewmodel_notified_when_application_deactivated()
        {
            // arrange
            resultUnderTest.Execute();

            // act
            phoenixApplication.OnDeactivated(new DeactivatedEventArgs());

            // assert
            Assert.IsTrue(viewResultTestViewModel.WasDeactivated);
        }

        [TestMethod]
        public void cannot_dispose_twice()
        {
            resultUnderTest.Dispose();
            AssertEx.Throws<ObjectDisposedException>(()=>resultUnderTest.Dispose());
        }
    }
}
